package cn.com.bsoft.mobile.controller


import cn.com.bsoft.mobile.dao.MobileArchiveDao
import cn.com.bsoft.mobile.entity.MobileArchive
import cn.com.bsoft.mobile.model.*
import cn.com.bsoft.mobile.service.AppMessageService
import cn.com.bsoft.mobile.service.FeedbackService
import cn.com.bsoft.mobile.service.MobileDeviceService
import cn.com.bsoft.mobile.service.toRsp
import cn.net.xyan.blossom.core.utils.absoluteURL
import cn.net.xyan.blossom.kotlin.AllOpen
import cn.net.xyan.blossom.kotlin.StatusAndMessageError

import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile

@Controller
@AllOpen
@RequestMapping("/app")
//@NeedLogInterceptor
class DeviceController {

    @Autowired
    lateinit var deviceService: MobileDeviceService

    @Autowired
    lateinit var msgService: AppMessageService

    @Autowired
    lateinit var archiveDao: MobileArchiveDao

    @Autowired
    lateinit var feedbackService: FeedbackService

    @RequestMapping("/link", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun link(@RequestBody req: LinkUserAppDeviceReq): Boolean {
        deviceService.link(req)
        return true
    }

    @RequestMapping("/remove", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun remove(@RequestBody req: RemoveUserAppDeviceReq): Boolean {
        deviceService.remove(req)
        return true
    }

    @RequestMapping("/simple/{msg}", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun simpleMessage(@PathVariable msg: String): List<AppMessageRsp> {
        return msgService.createSimpleMessage(msg, null, null).map {
            msgService.convertMessage(it)
        }
    }

    @RequestMapping("/query", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun queryMessage(@RequestBody req: QueryAppMessageReq): List<AppMessageRsp> {
        return msgService.queryMessage(req, null).map {
            msgService.convertMessage(it)
        }
    }

    @RequestMapping("/read", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun readMessage(@RequestBody req: List<String>): List<AppMessageRsp> {

        return req.map {
            msgService.convertMessage(msgService.readMessage(it))
        }
    }

    @RequestMapping("/archive/{archiveID}", method = arrayOf(RequestMethod.GET)
            ,produces = arrayOf(MediaType.IMAGE_PNG_VALUE,MediaType.IMAGE_GIF_VALUE,MediaType.IMAGE_JPEG_VALUE
            ,MediaType.TEXT_PLAIN_VALUE,MediaType.APPLICATION_XML_VALUE,MediaType.APPLICATION_JSON_UTF8_VALUE
            ,MediaType.APPLICATION_OCTET_STREAM_VALUE))
    @ResponseBody
    fun archive(@PathVariable archiveID: String): HttpEntity<ByteArray> {

        val archive = archiveDao.findOne(archiveID)

        val fileName = archive.fileName
        val header = HttpHeaders()

//        header.contentType = try {
//            MediaType.parseMediaType(archive?.mimeType ?: MediaType.APPLICATION_OCTET_STREAM_VALUE)
//        } catch (e: Throwable) {
//            MediaType.APPLICATION_OCTET_STREAM
//        }

        header.set("Content-Type",archive?.mimeType?:MediaType.APPLICATION_OCTET_STREAM_VALUE)

        header.set("Content-Disposition", "inline; filename=$fileName")
        header.contentLength = archive?.data?.size?.toLong() ?: 0L

        return HttpEntity(archive?.data ?: throw StatusAndMessageError("data is null"), header)
    }

    @RequestMapping("/archive", method = arrayOf(RequestMethod.POST), produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun upload(@RequestParam("archive") file: MultipartFile): ArchiveRsp {

        var archive = MobileArchive()
        archive.mimeType = file.contentType
        archive.fileName = file.originalFilename
        archive.data = file.bytes

        archive = archiveDao.saveAndFlush(archive)

        val url = absoluteURL("/app/archive/${archive.uuid}")

        var rsp = ArchiveRsp()

        rsp.archiveID = archive.uuid

        rsp.archiveURL = url

        return rsp
    }

    @RequestMapping("/feedback", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun feedback(@RequestBody req: FeedbackReq): FeedbackRsp {
        return feedbackService.create(req).toRsp()
    }

    @RequestMapping("/queryFeedback", produces = arrayOf(MediaType.APPLICATION_JSON_UTF8_VALUE))
    @ResponseBody
    fun queryFeedback(@RequestBody req: QueryFeedbackReq): List<FeedbackRsp> {
        return feedbackService.query(req).map { it.toRsp() }
    }


}